package com.mzj.saas.sdk.pay.alipay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.mzj.saas.sdk.pay.vo.AliPay;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付宝支付类
 *
 * @author hp
 */
public class AliPayRequest {

    private final static Logger logger = LoggerFactory.getLogger(AliPayRequest.class);
    private static final String ALIPAY_GATEWAY_URL = "https://openapi.alipay.com/gateway.do";
    private static final String FORMAT = "json";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";

    private AliPay aliPay;

    public AliPayRequest(AliPay aliPay) {
        this.aliPay = aliPay;
    }

    /**
     * 获取支付宝客户端对象
     *
     * @return
     */
    private AlipayClient getAlipayClient() {

        if (StringUtils.isBlank(aliPay.getAppId())) {
            logger.error("AliPayRequest appid is null");
            return null;
        }
        if (StringUtils.isBlank(aliPay.getPrivateKey())) {
            logger.error("AliPayRequest privateKey is null");
            return null;
        }
        if (StringUtils.isBlank(aliPay.getPublicKey())) {
            logger.error("AliPayRequest publicKey is null");
            return null;
        }

        return new DefaultAlipayClient(ALIPAY_GATEWAY_URL, aliPay.getAppId(), aliPay.getPrivateKey(), FORMAT, CHARSET, aliPay.getPublicKey(), SIGN_TYPE);
    }


    /**
     * APP支付接口2.0
     * 支付宝接口文档地址：https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay?scene=common
     *
     * @return 失败返回null，成功返回响应数据
     */
    public Map<String, Object> appPay() {
        try {

            if (aliPay == null) {
                logger.error("appPay---> aliPay is null");
                return null;
            }
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setOutTradeNo(aliPay.getOutTradeNo());
            model.setTotalAmount(aliPay.getTotalAmount());
            model.setSubject(aliPay.getSubject());
            if (StringUtils.isNotBlank(aliPay.getProductCode())) {
                model.setProductCode(aliPay.getProductCode());
            }
            if (StringUtils.isNotBlank(aliPay.getPassbackParams())) {
                model.setPassbackParams(URLEncoder.encode(aliPay.getPassbackParams(), "UTF-8"));
            }
            request.setBizModel(model);
            request.setNotifyUrl(aliPay.getNotifyUrl());

            AlipayClient alipayClient = this.getAlipayClient();
            if (alipayClient == null) {
                logger.error("[AliPay App Pay] Get AlipayClient Failed!");
                return null;
            }

            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (response.isSuccess()) {
                logger.info("[AliPay App Pay Success!] Ali Response={}", JSONObject.toJSONString(response));
                // 获取需提交的form表单
                Map<String, Object> paymentUpParamMap = new HashMap<String, Object>();
                paymentUpParamMap.put("body", response.getBody());
                return paymentUpParamMap;
            } else {
                logger.error("[AliPay App Pay Failed!] Ali Response={}", JSONObject.toJSONString(response));
                return null;
            }
        } catch (Exception e) {
            logger.error("appPay---> 支付宝支付异常，Exception={}", e);
            return null;
        }
    }

    /**
     * 扫码支付
     *
     * @return
     */
    public Map<String, Object> scanPay() {
        try {
            if (aliPay == null) {
                logger.error("scanPay---> aliPay is null");
                return null;
            }

            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
            request.setNotifyUrl(aliPay.getNotifyUrl());
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", aliPay.getOutTradeNo());
            bizContent.put("total_amount", aliPay.getTotalAmount());
            bizContent.put("subject", aliPay.getSubject());
            request.setBizContent(bizContent.toString());

            AlipayClient alipayClient = this.getAlipayClient();
            if (alipayClient == null) {
                logger.error("[AliPay scanPay] Get AlipayClient Failed!");
                return null;
            }
            AlipayTradePrecreateResponse response = alipayClient.execute(request);

            if (response.isSuccess()) {
                logger.info("[AliPay scanPay Success!] Ali Response={}", JSONObject.toJSONString(response));
                // 获取需提交的form表单
                Map<String, Object> paymentUpParamMap = new HashMap<String, Object>();
                paymentUpParamMap.put("mchid", aliPay.getAppId());
                paymentUpParamMap.put("privateKey", aliPay.getPrivateKey());
                paymentUpParamMap.put("publicKey", aliPay.getPublicKey());
                paymentUpParamMap.put("outTradeNo", response.getOutTradeNo());
                paymentUpParamMap.put("codeUrl", response.getQrCode());
                return paymentUpParamMap;
            } else {
                logger.error("[AliPay scanPay Failed!] Ali Response={}", JSONObject.toJSONString(response));
                return null;
            }
        } catch (Exception e) {
            logger.error("scanPay---> 支付宝支付异常，Exception={}", e);
            return null;
        }
    }

    /**
     * 查询订单
     *
     * @return
     */
    public Map<String, Object> orderQuery() {
        try {
            if (aliPay == null) {
                logger.error("orderQuery---> aliPay is null");
                return null;
            }

            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", aliPay.getOutTradeNo());
            request.setBizContent(bizContent.toString());

            AlipayClient alipayClient = this.getAlipayClient();
            if (alipayClient == null) {
                logger.error("[AliPay orderQuery] Get AlipayClient Failed!");
                return null;
            }
            AlipayTradeQueryResponse response = alipayClient.execute(request);

            Map<String, Object> paymentUpParamMap = new HashMap<String, Object>();
            if (response.isSuccess()) {
                logger.info("[AliPay orderQuery Success!] Ali Response={}", JSONObject.toJSONString(response));
                String tradeStatus = response.getTradeStatus();
                if("TRADE_SUCCESS".equals(tradeStatus)){
                    paymentUpParamMap.put("tradeState", "SUCCESS");
                }else {
                    paymentUpParamMap.put("tradeState", "FAIL");
                }
                return paymentUpParamMap;
            } else {
                logger.info("[AliPay orderQuery Failed!] Ali Response={}", JSONObject.toJSONString(response));
                if (response.getSubCode().equals("ACQ.TRADE_NOT_EXIST")){
                    paymentUpParamMap.put("tradeState", "FAIL");
                    return paymentUpParamMap;
                }
                return null;
            }
        } catch (Exception e) {
            logger.error("scanPay---> 支付宝查询订单异常，Exception={}", e);
            return null;
        }
    }

    public static void main(String[] args) throws AlipayApiException {
        String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqSxMRQxlREIbRLzXsj3M3EoOfdDR1pSg/1PdD3Gsu7j2vkCD0eE1fRkJr5IuLTGESuuqudTY+NTR9Uo9OnL5pNr2jmCADjnJ0PbJQsif/Vf2wGaqLH6lhFNuIDBeIyc3IudUiZ6SEt7UyB9pBSTw0QA0Ew8JmQDeL1RknGrt0RZVv7h6qiCiRRy+qC8kV1OSTddS59eb4t2ffzaFeL0Q9Ly8lUp1MGW3mvi9/soIy5b8DHDO7ofYVDmUKqWnFY2yqRjiuckRQuuzZbhRrJpEhHXyj+4j4QKFQHDayRn2Mf6rYTAA5bINmBULg2LWIcS8530oisn6RnJiBSymYryRPAgMBAAECggEAaS3s0GoL+n1t2IjWL22yrn2MQ1AaoNnU+Nr1aiyQnY/sd10/viAns+bJuL/v+Uf/qDXrVwhdoo2mE8C1fvgU7wzZE5EehhozvYVZAKsKE7GZ4q2TB0PeeSuw5iFvi0P1MvBiA0D99Wq3WE94Jqjm8xnx/jqXkemwRgETep+gmbArMUa6Ls+5unXdPWN/TLj2uy4gPhw9KbzxEsjQMSNywlYjGVujn8qddOSVz67SRY5SK11yQVpIML0jacB/cjbc/Fl4r8AnYaWe4sTvScycgHihJ1f4luNicxzsaz8h9ry0cjK9HQEqOmWHGbYGcuJY8xL6tdgRXaHsfsKwTr5icQKBgQD/aWGeXUPU1i6SuZMSSCfGVHd5kiNmLt4VZmQyxQWD7fE3MI6Se8AajGs8iu3z7AoSClutWh39+YMCtT/jbSs90M27DyV345JWuPaIJRXcPb37Ld1G04QdC5eecfoyFSlGF6CHCnQmqO4aahLn84NioPkR0EOTPiLsPBF7Z5qzSQKBgQDq1T1MWb7NKgPGr5IxsIQYr0jg9iss4eGC/rLn3kfHuZKMwI96YLWnEDTNPhREuvrl8Q4Fj3ZUXfDkS/ahq0mrum3kasfQ394JvLebLmhKesqYcRIEKmR3Marx/pt7ssvOj5WYfizmA36aZXKFlpe11vvEJyV6jTJtA9MyQXwC1wKBgQCyyd3fsYGuF0/6vZTKE2BkYPRRUY8eFGi5qjcxouE9fO6Bp6flumK7MthORSJUwUI7ZqzOKGseQe8HkkDqvpyqZOPesbeUuOTTeB57JxqqVT4L+gsPbTjp7Bdyfm6ZaF7ABgIFBbhQ56flLaOWYsvx2qT/Zz4mcDSaEWJbdCbCoQKBgHfysZvFH3tmIYWj+lWdJuwA5IXb15PWULz7YeCjniB7PkrctKy6py6NTZskQXAV3cADz7ixXaycS0YhMvnDJx8rW6RXknazUpPArDv8iVK5w6/32U79ZFGpsfpnpX2ahxWcK7o3gLGASXONq+BmWlmMVQ8NO8yMQJyEXqUF49UDAoGAQBY5oHWOD4/Bxi/Xz904tzN2GPLZ3n8HrODGztQ49tAX1YXarQtVvbGt/iPqzPnF1T4dHVe5KC1Cutxm5ypFoLoPRulz5zFTSt0cIrMOZ9b2KTQzHM0QHrv00UuuerdhF548y2stkBDCRDmYoSPL6IZGYie5czqp659/sqM2wS8=";
        String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArDKoto2XQILFg5x3Q0n8fjCqwTLFgTevaxnBi9tVapTZo+kQGIpTrDElw3/03lNOOJj3U6VhWTUzh9e0nlOBAI063v/fFXkj0/IQCiUCtSUiWbGw/ZHYmy17/wSJ5fAi6h/EhixgoKPSWlANKWRUlMosbXtpthLQspoC5/J3G6s1t5cZMiRrQC0ezClaqE9OeKENA0Pt2AZtSllrKn0tOalvCQRGQYf/VT0zf+PWd7Mr5OzAvaU4q/i3pJ/nahU7YyyUbTwh/v7MDlk9DNQlNptjy9Q5bmSqb51RAm7w9nGiqhtXTyL68zdnWHmKZI4Bua3rY4U1RSgjDYuwaLVLrwIDAQAB";
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", "2021002144613172", privateKey, "json", "GBK", publicKey, "RSA2");
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl("");
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", "20211011010101003");
        bizContent.put("total_amount", 0.01);
        bizContent.put("subject", "测试商品");

        //// 商品明细信息，按需传入
        //JSONArray goodsDetail = new JSONArray();
        //JSONObject goods1 = new JSONObject();
        //goods1.put("goods_id", "goodsNo1");
        //goods1.put("goods_name", "子商品1");
        //goods1.put("quantity", 1);
        //goods1.put("price", 0.01);
        //goodsDetail.add(goods1);
        //bizContent.put("goods_detail", goodsDetail);

        //// 扩展信息，按需传入
        //JSONObject extendParams = new JSONObject();
        //extendParams.put("sys_service_provider_id", "2088511833207846");
        //bizContent.put("extend_params", extendParams);

        //// 结算信息，按需传入
        //JSONObject settleInfo = new JSONObject();
        //JSONArray settleDetailInfos = new JSONArray();
        //JSONObject settleDetail = new JSONObject();
        //settleDetail.put("trans_in_type", "defaultSettle");
        //settleDetail.put("amount", 0.01);
        //settleDetailInfos.add(settleDetail);
        //settleInfo.put("settle_detail_infos", settleDetailInfos);
        //bizContent.put("settle_info", settleInfo);

        //// 二级商户信息，按需传入
        //JSONObject subMerchant = new JSONObject();
        //subMerchant.put("merchant_id", "2088000603999128");
        //bizContent.put("sub_merchant", subMerchant);

        //// 业务参数信息，按需传入
        //JSONObject businessParams = new JSONObject();
        //businessParams.put("busi_params_key", "busiParamsValue");
        //bizContent.put("business_params", businessParams);

        //// 营销信息，按需传入
        //JSONObject promoParams = new JSONObject();
        //promoParams.put("promo_params_key", "promoParamsValue");
        //bizContent.put("promo_params", promoParams);

        request.setBizContent(bizContent.toString());
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }
}
